/*
 * This is based off the O3D display-fps sample, modified for this
 * window demo.
 *
 * Copyright 2009, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// *********************** SpinningCubeWindow **********************************

/***
 * A SpinningCubeWindow is a window that shows a 3d model.
 * @constructor.
 */
function __SpinningCubeWindow() {
}

/**
 * Makes __SpinningCubeWindow inherit from Window.
 */
__SpinningCubeWindow.prototype = new __Window();

/**
 * Initializes an __SpinningCubeWindow window
 * @param {Object} spec Intialization arguments. See __Window.init.
 */
__SpinningCubeWindow.prototype.init = function(spec) {
  __Window.prototype.init.call(this, spec);
  var ui = this.getUI();
  ui.addOnRenderWindow(this);

  this.modelPack = g_client.createPack();
  // Create a material.
  var myMaterial = this.modelPack.createObject('Material');

  // Set the material's drawList
  myMaterial.drawList = this.viewInfo.performanceDrawList;

  // Load the effect for our sphere from our textarea.
  var defaultEffect = this.modelPack.createObject('Effect');
  var fxString = document.getElementById('fx').value;
  defaultEffect.loadFromFXString(fxString);

  // Apply our effect to this material. The effect tells the 3D hardware
  // which shader to use.
  myMaterial.effect = defaultEffect;
  defaultEffect.createUniformParameters(myMaterial);

  this.animateAngle = 0;

  // Draw a cube using the effect we have loaded.
  var myShape = o3djs.primitives.createRainbowCube(this.modelPack,
                                                   myMaterial,
                                                   0.5);

  // Attach the cube to the root of this window's scene graph.
  var root = this.root;
  root.addShape(myShape);
  this.shape = myShape;

  // Generate the draw elements.
  root.createDrawElements(this.modelPack, null);

  // Eye-position, this is where our camera is at.
  var eye = [1.5, 1.0, 1.5];

  // Target, this is where our camera is pointed at.
  var target = [0, 0, 0];

  // Up-vector, this tells the camera which direction is 'up'.
  // We define the positive y-direction to be up in this example.
  var up = [0, 1, 0];

  this.viewInfo.drawContext.view = g_math.matrix4.lookAt(eye, target, up);
  this.setProjection();
};

/**
 * Closes a __SpinningCubeWindow.
 */
__SpinningCubeWindow.prototype.close = function() {
  var ui = this.getUI();
  ui.removeOnRenderWindow(this);
  this.root.removeShape(myShape);
  this.modelPack.destroy();
  __Window.prototype.resizeWindow.close(this, size);
};

/**
 * Handler for onRender.
 * @param {number} elapsedTime time in seconds since the last call to onRender.
 */
__SpinningCubeWindow.prototype.onRender = function(elapsedTime) {
  this.root.rotateY(elapsedTime * 2);
};

/**
 * Sets the projection matrix.
 */
__SpinningCubeWindow.prototype.setProjection = function() {
  // Create our projection matrix, with a vertical field of view of 45 degrees
  // a near clipping plane of 0.1 and far clipping plane of 100.
  var fovInRad = 45 * Math.PI / 180
  var nearPlane = 0.1;
  var farPlane = 100;
  var aspectRatio = this.rect.width / this.rect.height;
  this.setPerspective(
      fovInRad,
      aspectRatio,
      nearPlane,
      farPlane);
};

/**
 * Resizes this window.
 * @param {Point} size where x = width, y = height.
 */
__SpinningCubeWindow.prototype.resizeWindow = function(size) {
  __Window.prototype.resizeWindow.call(this, size);
  this.setProjection();
};

